package service

import (
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/slrun/callcenter/internal/pkg/freeswitch"
)

// CallStatus 呼叫状态
type CallStatus string

const (
	CallStatusNew        CallStatus = "new"
	CallStatusRinging    CallStatus = "ringing"
	CallStatusActive     CallStatus = "active"
	CallStatusHeld       CallStatus = "held"
	CallStatusTransfered CallStatus = "transfered"
	CallStatusCompleted  CallStatus = "completed"
	CallStatusFailed     CallStatus = "failed"
)

// CallInfo 呼叫信息
type CallInfo struct {
	UUID        string    `json:"uuid"`
	CallerID    string    `json:"caller_id"`
	CalleeID    string    `json:"callee_id"`
	Status      CallStatus `json:"status"`
	StartTime   time.Time `json:"start_time"`
	AnswerTime  time.Time `json:"answer_time"`
	EndTime     time.Time `json:"end_time"`
	Duration    int       `json:"duration"`
	RecordingID string    `json:"recording_id,omitempty"`
}

// CallControlService 呼叫控制服务
type CallControlService struct {
	fsClient *freeswitch.Client
	calls    map[string]*CallInfo
	mutex    sync.RWMutex
}

// NewCallControlService 创建呼叫控制服务
func NewCallControlService(fsClient *freeswitch.Client) *CallControlService {
	service := &CallControlService{
		fsClient: fsClient,
		calls:    make(map[string]*CallInfo),
	}

	// 初始化事件处理
	if fsClient != nil {
		service.initEventHandlers()
	}

	return service
}

// initEventHandlers 初始化事件处理器
func (s *CallControlService) initEventHandlers() {
	err := s.fsClient.SubscribeEvents(
		"CHANNEL_CREATE",
		"CHANNEL_PROGRESS",
		"CHANNEL_ANSWER",
		"CHANNEL_HOLD",
		"CHANNEL_UNHOLD",
		"CHANNEL_TRANSFER",
		"CHANNEL_HANGUP",
		"RECORD_START",
		"RECORD_STOP",
	)

	if err != nil {
		log.Printf("Failed to subscribe to events: %v", err)
		return
	}

	s.fsClient.StartEventHandler(func(event map[string]string) {
		eventName, ok := event["Event-Name"]
		if !ok {
			return
		}

		uuid, ok := event["Unique-ID"]
		if !ok {
			return
		}

		// 处理不同的事件
		switch eventName {
		case "CHANNEL_CREATE":
			s.handleChannelCreate(event, uuid)
		case "CHANNEL_PROGRESS":
			s.handleChannelProgress(uuid)
		case "CHANNEL_ANSWER":
			s.handleChannelAnswer(uuid)
		case "CHANNEL_HOLD":
			s.handleChannelHold(uuid)
		case "CHANNEL_UNHOLD":
			s.handleChannelUnhold(uuid)
		case "CHANNEL_TRANSFER":
			s.handleChannelTransfer(uuid)
		case "CHANNEL_HANGUP":
			s.handleChannelHangup(event, uuid)
		case "RECORD_START":
			s.handleRecordStart(event, uuid)
		case "RECORD_STOP":
			s.handleRecordStop(uuid)
		}
	})
}

// 事件处理函数
func (s *CallControlService) handleChannelCreate(event map[string]string, uuid string) {
	callerID := event["Caller-Caller-ID-Number"]
	calleeID := event["Caller-Destination-Number"]

	s.mutex.Lock()
	defer s.mutex.Unlock()

	s.calls[uuid] = &CallInfo{
		UUID:     uuid,
		CallerID: callerID,
		CalleeID: calleeID,
		Status:   CallStatusNew,
		StartTime: time.Now(),
	}

	log.Printf("Call created: %s, caller: %s, callee: %s", uuid, callerID, calleeID)
}

func (s *CallControlService) handleChannelProgress(uuid string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if call, exists := s.calls[uuid]; exists {
		call.Status = CallStatusRinging
		log.Printf("Call ringing: %s", uuid)
	}
}

func (s *CallControlService) handleChannelAnswer(uuid string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if call, exists := s.calls[uuid]; exists {
		call.Status = CallStatusActive
		call.AnswerTime = time.Now()
		log.Printf("Call answered: %s", uuid)
	}
}

func (s *CallControlService) handleChannelHold(uuid string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if call, exists := s.calls[uuid]; exists {
		call.Status = CallStatusHeld
		log.Printf("Call held: %s", uuid)
	}
}

func (s *CallControlService) handleChannelUnhold(uuid string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if call, exists := s.calls[uuid]; exists {
		call.Status = CallStatusActive
		log.Printf("Call unheld: %s", uuid)
	}
}

func (s *CallControlService) handleChannelTransfer(uuid string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if call, exists := s.calls[uuid]; exists {
		call.Status = CallStatusTransfered
		log.Printf("Call transfered: %s", uuid)
	}
}

func (s *CallControlService) handleChannelHangup(event map[string]string, uuid string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if call, exists := s.calls[uuid]; exists {
		call.Status = CallStatusCompleted
		call.EndTime = time.Now()
		if !call.AnswerTime.IsZero() {
			call.Duration = int(call.EndTime.Sub(call.AnswerTime).Seconds())
		}
		log.Printf("Call completed: %s, duration: %d seconds", uuid, call.Duration)
	}
}

func (s *CallControlService) handleRecordStart(event map[string]string, uuid string) {
	recordingID := event["Record-File"]

	s.mutex.Lock()
	defer s.mutex.Unlock()

	if call, exists := s.calls[uuid]; exists {
		call.RecordingID = recordingID
		log.Printf("Recording started for call %s: %s", uuid, recordingID)
	}
}

func (s *CallControlService) handleRecordStop(uuid string) {
	log.Printf("Recording stopped for call %s", uuid)
}

// 呼叫控制API

// MakeCall 发起呼叫
func (s *CallControlService) MakeCall(callerID, calleeID string) (*CallInfo, error) {
	if s.fsClient == nil {
		return nil, fmt.Errorf("FreeSWITCH client not initialized")
	}

	options := map[string]string{
		"originate_timeout": "60",
	}

	uuid, err := s.fsClient.OriginateCall(callerID, calleeID, options)
	if err != nil {
		return nil, fmt.Errorf("failed to make call: %w", err)
	}

	// 等待呼叫信息被事件处理器创建
	time.Sleep(100 * time.Millisecond)

	s.mutex.RLock()
	defer s.mutex.RUnlock()

	call, exists := s.calls[uuid]
	if !exists {
		return nil, fmt.Errorf("call not found: %s", uuid)
	}

	return call, nil
}

// HangupCall 挂断呼叫
func (s *CallControlService) HangupCall(uuid string) error {
	if s.fsClient == nil {
		return fmt.Errorf("FreeSWITCH client not initialized")
	}

	err := s.fsClient.HangupCall(uuid)
	if err != nil {
		return fmt.Errorf("failed to hangup call: %w", err)
	}

	return nil
}

// HoldCall 保持呼叫
func (s *CallControlService) HoldCall(uuid string) error {
	if s.fsClient == nil {
		return fmt.Errorf("FreeSWITCH client not initialized")
	}

	err := s.fsClient.HoldCall(uuid)
	if err != nil {
		return fmt.Errorf("failed to hold call: %w", err)
	}

	return nil
}

// UnholdCall 取消保持
func (s *CallControlService) UnholdCall(uuid string) error {
	if s.fsClient == nil {
		return fmt.Errorf("FreeSWITCH client not initialized")
	}

	err := s.fsClient.UnholdCall(uuid)
	if err != nil {
		return fmt.Errorf("failed to unhold call: %w", err)
	}

	return nil
}

// TransferCall 转接呼叫
func (s *CallControlService) TransferCall(uuid, destination string) error {
	if s.fsClient == nil {
		return fmt.Errorf("FreeSWITCH client not initialized")
	}

	err := s.fsClient.TransferCall(uuid, destination)
	if err != nil {
		return fmt.Errorf("failed to transfer call: %w", err)
	}

	return nil
}

// Conference 三方通话
func (s *CallControlService) Conference(uuid1, uuid2 string) error {
	if s.fsClient == nil {
		return fmt.Errorf("FreeSWITCH client not initialized")
	}

	err := s.fsClient.BridgeCall(uuid1, uuid2)
	if err != nil {
		return fmt.Errorf("failed to create conference: %w", err)
	}

	return nil
}

// RecordCall 录音呼叫
func (s *CallControlService) RecordCall(uuid string) error {
	if s.fsClient == nil {
		return fmt.Errorf("FreeSWITCH client not initialized")
	}

	// 生成录音文件名
	filename := fmt.Sprintf("call_%s", time.Now().Format("20060102_150405"))

	err := s.fsClient.RecordCall(uuid, filename, "wav")
	if err != nil {
		return fmt.Errorf("failed to start recording: %w", err)
	}

	return nil
}

// StopRecording 停止录音
func (s *CallControlService) StopRecording(uuid string) error {
	if s.fsClient == nil {
		return fmt.Errorf("FreeSWITCH client not initialized")
	}

	err := s.fsClient.StopRecording(uuid)
	if err != nil {
		return fmt.Errorf("failed to stop recording: %w", err)
	}

	return nil
}

// GetCallInfo 获取呼叫信息
func (s *CallControlService) GetCallInfo(uuid string) (*CallInfo, error) {
	s.mutex.RLock()
	defer s.mutex.RUnlock()

	call, exists := s.calls[uuid]
	if !exists {
		return nil, fmt.Errorf("call not found: %s", uuid)
	}

	return call, nil
}

// GetActiveCalls 获取所有活跃呼叫
func (s *CallControlService) GetActiveCalls() []*CallInfo {
	s.mutex.RLock()
	defer s.mutex.RUnlock()

	var activeCalls []*CallInfo
	for _, call := range s.calls {
		if call.Status == CallStatusNew || 
		   call.Status == CallStatusRinging || 
		   call.Status == CallStatusActive || 
		   call.Status == CallStatusHeld {
			activeCalls = append(activeCalls, call)
		}
	}

	return activeCalls
}

// SendDTMF 发送DTMF
func (s *CallControlService) SendDTMF(uuid, digits string) error {
	if s.fsClient == nil {
		return fmt.Errorf("FreeSWITCH client not initialized")
	}

	err := s.fsClient.SendDTMF(uuid, digits)
	if err != nil {
		return fmt.Errorf("failed to send DTMF: %w", err)
	}

	return nil
}